#include <QtCore/QCoreApplication>

#include <stdio.h>
#include <stdlib.h>

#include "../DataFlow.h"

using namespace DataFlow;

class Task0 : public Task
{
	public:

		virtual void run(const ArgumentArray & input, ArgumentArray & output)
		{
			//printf("T0\n");
			output[0] = input[0].toInt();
			output[1] = input[0].toInt() * 2;
		}
};

class Task1 : public Task
{
	public:

		virtual void run(const ArgumentArray & input, ArgumentArray & output)
		{
			//printf("T1\n");
			output[0] = input[0].toInt() * 2;
		}
};

class Task2 : public Task
{
	public:

		virtual void run(const ArgumentArray & input, ArgumentArray & output)
		{
			//printf("T2\n");
			output[0] = input[0].toInt() * 4;
		}
};

class Task3 : public Task
{
	public:

		virtual void run(const ArgumentArray & input, ArgumentArray & output)
		{
			//printf("T3\n");
			output[0] = input[0].toInt() + input[1].toInt();
			printf("OUT[%d]: %d\n", output.id(), output[0].toInt());
		}
};

int main(int argc, char *argv[])
{
	QCoreApplication a(argc, argv);

	srand(12345);

	Task0 task0;
	Task1 task1;
	Task2 task2;
	Task3 task3;

	DataFlow::initialize();

	// nodesCount, sourceOutputsCount, sinkInputsCount
	Graph g(4, 1, 1);

	// nodeID, inputsCount, outputsCount, maxTime, task
	g.setNode(0, 1, 2, 0, &task0);
	g.setNode(1, 1, 1, 0, &task1);
	g.setNode(2, 1, 1, 0, &task2);
	g.setNode(3, 2, 1, 0, &task3);

	// OUTPUT(sourceNodeID, sourceNodeOutputChannel), INPUT(destinationNodeID, destinationNodeInputChannel), queueSize = 0
	g.link(SOURCE(   0), INPUT(0, 0));
	g.link(OUTPUT(0, 0), INPUT(1, 0));
	g.link(OUTPUT(0, 1), INPUT(2, 0));
	g.link(OUTPUT(1, 0), INPUT(3, 0));
	g.link(OUTPUT(2, 0), INPUT(3, 1));

	Executor e(g);
	QObject::connect(&e, SIGNAL(finished()), &a, SLOT(quit()));

	// nodeID, inputID, arg0, ...
	for (int i=0; i<100; ++i)
	{
		if ((i % 1000) == 0) printf("%d\n", i);
		e << DATA(INPUT(0, 0), VALUE(i, i * 10));
	}

	//e.waitForFinished();

	const int r = a.exec();
	system("pause");
	return r;
}
